#pragma once


#include "base/core/singleton.h"
#include "base/core/object_pool.h"
#include <map>
#include "Drop.h"
#include "base/core/point3.h"
#include "Common/Item/ItemMgr.h"
#include "Common/TableData/DropDropCfg.h"
#include "Scene/SceneMgr.h"
#include "Common/Event/Event.h"
#include "Common/Timer/TimerAxis.h"


class Creature;
class DropMgr :public IEventExecuteSink, public ITimerHandler, public ManualSingleton < DropMgr >
{
	friend class ManualSingleton < DropMgr >;
	typedef std::unordered_map<uint64_t, Drop*> MapDrop;
	typedef std::list<CharIDType> CidLst;
public:
	DropMgr();
	~DropMgr();
public:
	bool Init();
	bool UnInit();
	bool Update(uint64_t tick);
	//////////////////////////////////////////////////////////////////////////
	virtual void OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen);
	//////////////////////////////////////////////////////////////////////////
	virtual void OnTimer(uint32_t nTimerID);
public:
	//玩家独立掉落
	bool AddDrop(Creature *pCreature, Point3<float>&pos, uint32_t nDropID, uint32_t monsId, int32_t monsLev,SDropSourcePram &source);
	//添加野外掉落
	bool AddWildDrop(Creature *pCreature, uint32_t sceneId, Point3<float>&pos, int32_t monsDropType, uint32_t dropId, uint32_t monsId, int32_t monsLev, SDropSourcePram &source);
	//添加工会掉落
	bool AddUnionDrop(uint32_t sceneId, Point3<float>&pos, uint32_t dropId, SET_UINT32 &setUnion, SDropSourcePram &source);
	//添加工会掉落，通过玩家背包掉落
	bool AddUnionDropByPlayer(uint32_t sceneId, Point3<float>&pos, CharIDType charId, int32_t itemSubType, SET_UINT32 &setUnion, SDropSourcePram &source);
	//移除掉落
	bool RemoveDrop(uint64_t dropCid);
	//安全区掉落
	bool PlayerSafeAreaDrop(CharIDType charId, Point3<float>&pos, int32_t itemSubType, SDropSourcePram &source);
	//玩家下线掉落
	bool PlayerLogoutDrop(CharIDType charId, int32_t itemSubType, SDropSourcePram &source);
	//玩家死亡掉落处理
	void OnPlayerDieDrop(Player *pDiePlayer, CharIDType killerCid, MAP_UINT32_INT32 &mapDropItem, bool &removeItemFalg, SDropSourcePram &source);
	//怪物HP掉落
	bool OnMonsHpDrop(uint32_t sceneId, uint32_t dropId, Point3<float> pos, uint32_t monsId, int32_t monsLev, SDropSourcePram &source);
	//获取玩家box条件
	void GetBoxCond(CharIDType cid, BoxCondCfg &boxCond);
	//获取玩家box条件
	void GetBoxCond(Player *pPlayer, BoxCondCfg &boxCond);
	//获取玩家物品条件
	void GetItemCond(CharIDType cid, SItemCond &itemCond, EItemInitAttrType initType = EItemInitAttrType_Common);
	//获取玩家物品条件
	void GetItemCond(Player *pPlayer, SItemCond &itemCond, EItemInitAttrType initType = EItemInitAttrType_Common);
public:
	/////////////////////////////////////// 宝箱掉落（包括礼包，翻牌等，除开怪物掉落以外的掉落） ///////////////////////////////////
	//玩家添加宝箱物品
	ERetCode PlayerAddBox(Player *pPlayer, VEC_INT32 &nBoxIdList,SItemSourceParam &souceParam);
	//使用物件掉落
	void UseThingDrop(Player *pPlayer, uint32_t monsterId, int32_t monsLev, Point3<float> &pos);
private:
	//通用掉落
	void PlayerDieCommonDrop(Player *pDiePlayer, int8_t byType, int32_t dropNum,MAP_UINT32_INT32 &mapDropItem,SDropSourcePram &source);
	//玩家死亡活动掉落
	void PlayerDieDropByAct(Player *pDiePlayer, MAP_UINT32_INT32 &mapDropItem,SDropSourcePram &source, CharIDType killerId = 0/*如果被击杀，则为击杀者cid*/);
	//普通场景掉落
	bool AddNormalDrop(Creature *pCreature, Scene *pScene, uint32_t nDropID, int32_t monsDropType, Point3<float> &midPos, uint32_t monsId, int32_t monsLev, SDropSourcePram &source, int32_t itemReduce = DROP_RAND_BASE_NUM, int32_t goldReduce = DROP_RAND_BASE_NUM);
	//添加掉落
	bool AddDrop(Creature *pCreature, Scene *pScene, uint32_t nDropID, Point3<float> &midPos, int8_t byDropType, SET_UINT64 &setTypeVal, uint32_t monsId, int32_t monsLev, int32_t dropInitProtect, int32_t openReduce, SDropSourcePram &source, int32_t itemReduce = DROP_RAND_BASE_NUM, int32_t goldReduce = DROP_RAND_BASE_NUM);
	//创建掉落
	bool CreateDrop(uint32_t nDropID, uint32_t nSceneID, Point3<float> &midPos, int8_t byDropType, SET_UINT64 &setTypeVal, uint32_t monsId, int32_t monsLev, int32_t dropInitProtect, SDropSourcePram &source);
	//创建掉落
	bool CreateDrop(uint32_t nDropID, Scene *pScene, Point3<float> &midPos, int8_t byDropType, SET_UINT64 &setTypeVal, uint32_t monsId, int32_t monsLev, int32_t dropInitProtect, SDropSourcePram &source, int32_t itemReduce = DROP_RAND_BASE_NUM, int32_t goldReduce = DROP_RAND_BASE_NUM);
	//创建掉落
	bool CreateDrop(VEC_ITEM_PROTO_EX &vecProtoEx, VEC_UINT32 &vecGold, Scene *pScene, Point3<float> &midPos, int8_t byDropType, SET_UINT64 &setTypeVal, int32_t dropInitProtect, SDropSourcePram &source);
	//怪物死亡掉落
	void OnMonsterDieDrop(DieEvent *pDieEvent);
	
	//计算死亡经验
	void OnCreatureDieExp(Creature * pCreature);
	//通知衰减后得经验
	int32_t OnReduceCreatureDieExp(Player * pPlayer,Monster * pCreature,int32_t exp);
	//背包掉落
	void PackageDrop(Player *pPlayer,Point3<float> pos, VEC_COMMON_ITEM &vecPackageItem, SET_Drop &setDrop, MAP_UINT16_INT32 &mapIdxNum, int8_t byDropType, SET_UINT64 &setTypeVal,SDropSourcePram &source, CharIDType fromWho = 0);
	//任务杀怪
	void OnMissionKillMons(DieEvent &dieEvent, int32_t monsLev, Point3<float> &pos);
	//任务掉落
	void OnMissionDrop(Player *pPlayer, uint32_t monsterId, int32_t monsLev, Point3<float> &pos);
	//动态怪掉落
	void OnDyMonsDrop(uint32_t monsId, int32_t monsLev, VEC_ITEM_PROTO_EX &vecProtoEx, VEC_UINT32 &vecGold,SItemCond &itemCond, int32_t goldReduce, int32_t itemReduce);
	//活动期间怪物掉落
	void OnMonsDropDuringAct(uint32_t monsId,VEC_ITEM_PROTO_EX &vecProtoEx, VEC_UINT32 &vecGold, int32_t goldReduce, int32_t itemReduce);
	//获取怪物掉落参数
	void GetMonsDropParam(uint32_t monsId, int32_t &openReduce, int32_t &dropInitProtect);
	//获取怪物掉落参数
	void GetMonsDropParam(const MonsterMonsterCfgInfo *pMonsCfg, int32_t &openReduce, int32_t &dropInitProtect);
	//传送区域附近找有效坐标
	void FindPointLstInTelp(Player *p, Point3<float> &pos);
};

#define g_MakeDropMgr() (DropMgr::Instance())
#define g_GetDropMgr() (DropMgr::GetInstance())
#define g_DelDropMgr() (DropMgr::Destroy())
